]> dgit.raspbian.org Git - opencv.git/commitdiff
videoio: fix build with FFmpeg 9 after AVCodec::pix_fmts and supported_framerates...
authorAadhu23 <aadhavansalthivel5@gmail.com>
Sat, 19 Sep 2026 09:07:54 +0000 (17:07 +0800)
committerAron Xu <aron@debian.org>
Sat, 19 Sep 2026 09:07:54 +0000 (17:07 +0800)
Origin: backport, https://github.com/opencv/opencv/pull/29533
Bug: https://github.com/opencv/opencv/issues/29504
Bug: https://github.com/opencv/opencv/issues/29655
Bug-Debian: https://bugs.debian.org/1144031
Forwarded: not-needed
Reviewed-by: Aron Xu <aron@debian.org>
Last-Update: 2026-09-19

Gbp-Pq: Name ffmpeg-9.0-compat.patch

modules/videoio/src/cap_ffmpeg_hw.hpp
modules/videoio/src/cap_ffmpeg_impl.hpp

index 0998ee9f483c154bdec0562f208377d864547dc8..2ecdc55dd59960c830cd433ff34d1e37be85d6ff 100644 (file)
@@ -738,6 +738,30 @@ AVCodec *hw_find_codec(AVCodecID id, AVHWDeviceType hw_type, int (*check_categor
 #endif
             if (hw_type == AV_HWDEVICE_TYPE_CUDA) // CUDA encoders don't support avcodec_get_hw_config()
                 hw_native_fmt = AV_PIX_FMT_CUDA;
+#if LIBAVCODEC_BUILD >= AV_VERSION_INT(61, 13, 100)
+            if (av_codec_is_encoder(c) && hw_native_fmt != AV_PIX_FMT_NONE) {
+                const AVPixelFormat *pix_fmts = NULL;
+                int num_pix_fmts = 0;
+
+                int ret = avcodec_get_supported_config(
+                    NULL,
+                    c,
+                    AV_CODEC_CONFIG_PIX_FORMAT,
+                    0,
+                    (const void **)&pix_fmts,
+                    &num_pix_fmts);
+
+                if (ret >= 0 && pix_fmts && num_pix_fmts > 0) {
+                        for (int i = 0; i < num_pix_fmts; i++) {
+                            if (pix_fmts[i] == hw_native_fmt) {
+                                *hw_pix_fmt = hw_native_fmt;
+                                if (hw_check_codec(c, hw_type, disabled_codecs))
+                                    return c;
+                            }
+                        }
+                    }
+            }
+#else
             if (av_codec_is_encoder(c) && hw_native_fmt != AV_PIX_FMT_NONE && c->pix_fmts) {
                 for (int i = 0; c->pix_fmts[i] != AV_PIX_FMT_NONE; i++) {
                     if (c->pix_fmts[i] == hw_native_fmt) {
@@ -747,6 +771,7 @@ AVCodec *hw_find_codec(AVCodecID id, AVHWDeviceType hw_type, int (*check_categor
                     }
                 }
             }
+#endif
             for (int i = 0;; i++) {
                 const AVCodecHWConfig *hw_config = avcodec_get_hw_config(c, i);
                 if (!hw_config)
index 11288036212e92432abffdf43bd1e80af2b01860..393b1c801c3d183c40e570e2a29e3be6e6bb6252 100644 (file)
@@ -2292,6 +2292,38 @@ static AVCodecContext * icv_configure_video_stream_FFMPEG(AVFormatContext *oc,
     c->time_base.den = frame_rate;
     c->time_base.num = frame_rate_base;
     /* adjust time base for supported framerates */
+#if LIBAVCODEC_BUILD >= CALC_FFMPEG_VERSION(61, 13, 100)
+    if (codec){
+        const AVRational *supported_framerates = NULL;
+        int num_supported_framerates = 0;
+        int ret = avcodec_get_supported_config(NULL, codec, AV_CODEC_CONFIG_FRAME_RATE, 0,
+                                               (const void **)&supported_framerates, &num_supported_framerates);
+
+        if (ret >= 0 && supported_framerates && num_supported_framerates > 0){
+            AVRational req = {frame_rate, frame_rate_base};
+            const AVRational *best=NULL;
+            AVRational best_error= {INT_MAX, 1};
+            for(int i = 0; i < num_supported_framerates; i++){
+                const AVRational *p = &supported_framerates[i];
+                AVRational error = av_sub_q(req, *p);
+                if(error.num <0) error.num *= -1;
+                if(av_cmp_q(error, best_error) < 0){
+                    best_error = error;
+                    best = p;
+                }
+            }
+            if (best == NULL)
+            {
+#ifdef CV_FFMPEG_CODECPAR
+                avcodec_free_context(&c);
+#endif
+                return NULL;
+            }
+            c->time_base.den = best->num;
+            c->time_base.num = best->den;
+        }
+    }
+#else
     if(codec && codec->supported_framerates){
         const AVRational *p= codec->supported_framerates;
         AVRational req = {frame_rate, frame_rate_base};
@@ -2315,6 +2347,7 @@ static AVCodecContext * icv_configure_video_stream_FFMPEG(AVFormatContext *oc,
         c->time_base.den= best->num;
         c->time_base.num= best->den;
     }
+#endif
 
     c->gop_size = 12; /* emit one intra frame every twelve frames at most */
     c->pix_fmt = pixel_format;